package com.lc.support.cardmsg

/**
 * Created by LC_Lin on 2016/5/28.
 */
interface Element {
    fun render(builder: StringBuilder, indent: String)
}

class TextElement(val text: String) : Element {
    override fun render(builder: StringBuilder, indent: String) {
        builder.append("$indent$text\n")
    }
}

abstract class Tag(val name: String) : Element {
    val children = arrayListOf<Element>()
    val attributes = hashMapOf<String, String>()

    protected fun <T : Element> initTag(tag: T, init: T.() -> Unit): T {
        tag.init()
        children.add(tag)
        return tag
    }

    override fun render(builder: StringBuilder, indent: String) {
        if (children.isEmpty()) {
            builder.append("$indent<$name${renderAttributes()}/>\n")
        }else{
            builder.append("$indent<$name${renderAttributes()}>\n")
            for (c in children) {
                c.render(builder, indent + "  ")
            }
            builder.append("$indent</$name>\n")
        }
    }

    private fun renderAttributes(): String? {
        val builder = StringBuilder()
        for (a in attributes.keys) {
            builder.append(" $a=\"${attributes[a]}\"")
        }
        return builder.toString()
    }


    override fun toString(): String {
        val builder = StringBuilder()
        render(builder, "")
        return builder.toString()
    }
}

abstract class TagWithText(name: String) : Tag(name) {
    operator fun String.unaryPlus() {
        children.add(TextElement(this))
    }
}

class CardMsg() : TagWithText("msg") {
    var serviceId: String
        get() = attributes["serviceID"]!!
        set(value) {
            attributes["serviceID"] = value
        }

    var templateId: String
        get() = attributes["templateID"]!!
        set(value) {
            attributes["templateID"] = value
        }

    var action: String
        get() = attributes["action"]!!
        set(value) {
            attributes["action"] = value
        }

    var brief: String
        get() = attributes["brief"]!!
        set(value) {
            attributes["brief"] = value
        }

    var flag: String
        get() = attributes["flag "]!!
        set(value) {
            attributes["flag "] = value
        }

    var sourcePublicUin: String
        get() = attributes["sourcePublicUin"]!!
        set(value) {
            attributes["sourcePublicUin"] = value
        }

    var sourceMsgId: String
        get() = attributes["sourceMsgId"]!!
        set(value) {
            attributes["sourceMsgId"] = value
        }

    var url: String
        get() = attributes["url"]!!
        set(value) {
            attributes["url"] = value
        }

    var sTyoe: String
        get() = attributes["sTyoe"]!!
        set(value) {
            attributes["sType"] = value
        }

    var adverSign: String
        get() = attributes["adverSign"]!!
        set(value) {
            attributes["adverSign"] = value
        }

    var adverKey: String
        get() = attributes["adverKey"]!!
        set(value) {
            attributes["adverKey"] = value
        }

    var actionData: String
        get() = attributes["actionData"]!!
        set(value) {
            attributes["actionData"] = value
        }

    var aActionData: String
        get() = attributes["a_actionData"]!!
        set(value) {
            attributes["a_actionData"] = value
        }

    var iActionData: String
        get() = attributes["i_actionData"]!!
        set(value) {
            attributes["i_actionData"] = value
        }

    fun item(init: Item.() -> Unit) = initTag(Item(),init)

//    fun item(layout: String?, mode: String?, bg: String?, init: Item.() -> Unit): Item {
//        val item: Item = Item()
//        if (layout != null) {
//            item.layout = layout
//        }
//        if (mode != null) {
//            item.mode = mode
//        }
//        if (bg != null) {
//            item.bg = bg
//        }
//        return initTag(item, init)
//    }

    fun source(text: String = "By:LC丶Lin", icon: String = "", action: String = "", appid: String = "-1",
               actionData: String? = null, aActionData: String? = null, iActionData: String? = null): Source {
        val source: Source = Source()
        source.text = text
        source.icon = icon
        source.action = action
        source.appid = appid
        if (actionData != null) {
            source.actionData = actionData
        }
        if (aActionData != null) {
            source.aActionData = aActionData
        }
        if (iActionData != null) {
            source.iActionData = iActionData
        }
        return initTag(source) {}
    }
}

class Source : TagWithText("source") {
    var text: String
        get() = attributes["name"]!!
        set(value) {
            attributes["name"] = value
        }

    var icon: String
        get() = attributes["icon"]!!
        set(value) {
            attributes["icon"] = value
        }

    var action: String
        get() = attributes["action"]!!
        set(value) {
            attributes["action"] = value
        }

    var appid: String
        get() = attributes["appid"]!!
        set(value) {
            attributes["appid"] = value
        }

    var actionData: String
        get() = attributes["actionData"]!!
        set(value) {
            attributes["actionData"] = value
        }

    var aActionData: String
        get() = attributes["a_actionData"]!!
        set(value) {
            attributes["a_actionData"] = value
        }

    var iActionData: String
        get() = attributes["i_actionData"]!!
        set(value) {
            attributes["i_actionData"] = value
        }
}

abstract class ItemTag(name: String) : TagWithText(name) {
    fun button(init:Button.()->Unit) = initTag(Button(),init)
    fun hr(type:Int) = initTag(Hr(type)){}
    fun picture(init: Picture.() -> Unit) = initTag(Picture(), init)
    fun title(init: Title.() -> Unit) = initTag(Title(), init)
    fun summary(init: Summary.() -> Unit) = initTag(Summary(), init)
}

class Item : ItemTag("item") {
    var layout: String
        get() = attributes["layout"]!!
        set(value) {
            attributes["layout"] = value
        }

    var mode: String
        get() = attributes["mode"]!!
        set(value) {
            attributes["mode"] = value
        }

    var bg: String
        get() = attributes["bg"]!!
        set(value) {
            attributes["bg"] = value
        }
}

/**
 * x现在还不能使用
 */
class Audio : ItemTag("audio")

class Button: ItemTag("button"){
    var action: String
        get() = attributes["action"]!!
        set(value) {
            attributes["action"] = value
        }

    var url: String
        get() = attributes["url"]!!
        set(value) {
            attributes["url"] = value
        }

    var pActionData: String
        get() = attributes["p_actionData"]!!
        set(value) {
            attributes["p_actionData"] = value
        }

    var iActionData: String
        get() = attributes["i_actionData"]!!
        set(value) {
            attributes["i_actionData"] = value
        }

    var a_actionData: String
        get() = attributes["a_ActionData"]!!
        set(value) {
            attributes["a_actionData"] = value
        }
}

class Hr(type:Int): ItemTag("hr"){
    init {
        when (type) {
        1->attributes["hidden"] = "false"
        2->attributes["hidden"] = "true"
    }
    }
}
class Picture: ItemTag("picture"){
    var cover: String
        get() = attributes["cover"]!!
        set(value) {
            attributes["cover"] = value
        }
}
class Title: ItemTag("title"){
    var size: String
        get() = attributes["size"]!!
        set(value) {
            attributes["size"] = value
        }

    var color: String
        get() = attributes["color"]!!
        set(value) {
            attributes["color"] = value
        }
}
class Summary: ItemTag("summary"){
    var size: String
        get() = attributes["size"]!!
        set(value) {
            attributes["size"] = value
        }

    var color: String
        get() = attributes["color"]!!
        set(value) {
            attributes["color"] = value
        }
}

fun cardMsg(init:CardMsg.()->Unit):CardMsg{
    val cardMsg:CardMsg = CardMsg()
    cardMsg.init()
    return cardMsg
}

//fun cardMsg(serviceId: String? = null, templateId: String? = null, action: String? = null, brief: String? = null, flag: String? = null, sourcePublicUin: String? = null,
//            sourceMsgId: String? = null, url: String? = null, sType: String? = null, adverSign: String? = null, adverKey: String? = null, actionData: String? = null,
//            aActionData: String? = null, iActionData: String? = null, init: CardMsg.() -> Unit): CardMsg {
//    val cardMsg: CardMsg = CardMsg()
//    if (serviceId != null) {
//        cardMsg.serviceId = serviceId
//    }
//    if (templateId != null) {
//        cardMsg.templateId = templateId
//    }
//    if (action != null) {
//        cardMsg.action = action
//    }
//    if (brief != null) {
//        cardMsg.brief = brief
//    }
//    if (flag != null) {
//        cardMsg.flag = flag
//    }
//    if (sourcePublicUin != null) {
//        cardMsg.sourcePublicUin = sourcePublicUin
//    }
//    if (sourceMsgId != null) {
//        cardMsg.sourceMsgId = sourceMsgId
//    }
//    if (url != null) {
//        cardMsg.url = url
//    }
//    if (sType != null) {
//        cardMsg.sTyoe = sType
//    }
//    if (adverSign != null) {
//        cardMsg.adverSign = adverSign
//    }
//    if (adverKey != null) {
//        cardMsg.adverKey = adverKey
//    }
//    if (actionData != null) {
//        cardMsg.actionData = actionData
//    }
//    if (aActionData != null) {
//        cardMsg.aActionData = aActionData
//    }
//    if (iActionData != null) {
//        cardMsg.iActionData = iActionData
//    }
//    cardMsg.init()
//    return cardMsg
//}